1. Field of the Invention
The present invention relates to the fields of distributed computer systems, client-server computing, and object oriented programming. Specifically, the present invention relates to a method and apparatus for clients on different machines to communicate references to remote objects such that the receiving machine has as much information as wanted, neither more nor less, of the type of the remote object.
2. Background
In client-server computing, typically there is a set of computers that can communicate with one another through a network connecting the computers. A first computer in the network that is referred to as a client sends a request to a second computer in the network that is referred to as a server. In response to the request, the server takes action and generally provides data representing the results of the action to the client. The client-server model also generalizes to the case where distinct processes, running on the same computer, are communicating with one another through some protected mechanism and are acting as server and clients.
For examples of client-server systems see: (i) J. K. Ousterhout et al, "Medusa: An Experiment in Distributed Operating System Structure", Communications of the ACM 23(2),1980; (ii) R. M. Needham and A. J. Herbert, "The Cambridge Distributed Computing System", Addison-Wesley, 1982; and (iii) J. K. Ousterhout et al "The Sprite Distributed Operating System", IEEE Computer, 1988.
Object-oriented programs have proven very useful in the design and implementation of computer systems. Object oriented systems are known, but are described briefly here for completeness. In an object-oriented environment, computer instructions represent objects which have a state and a behavior. Components of the state of an object and the behavior of the object are defined by a class to which the object belongs. A class defines a number of attributes and member functions of the object which belong to the class. An attribute is a component of the state of an object and the value of an attribute can vary from one object of a class to another object of the class. For example, a class of tables can define a color attribute. Each object of the class of tables has a color attribute, but the value of the color attribute of one table can specify the color red while the value of the color attribute of another table can specify the color green. A member function is a collection of computer instructions and data which collectively define a task which can be performed by an object. For example, a table can be asked to bear a weight, and the behavior of the table in bearing the weight is defined by the member function provided by the table class for bearing a weight. In addition, the member function provided by the table class is performed in the context of the state of the particular table which is bearing the weight. For example, the state of a table can include various dimensions of the table, the materials from which the table is made, and the amount of weight already supported by the table. The specific behavior of the table in bearing the weight can include, for example, changes in the state of the table including adding the weight to the amount of weight already supported by the table or breaking under the additional weight.
A particularly helpful feature of object-oriented environments is generally referred to as inheritance. Inheritance refers to inheritance of attributes and member functions of one class from another class according to a class hierarchy. Each class can have one or more subclasses, each of which can add attributes and/or member functions and can redefine member functions. For example, a desk class is a subclass of the table class and defines an additional attribute which specifies the number of drawers of the desk. Thus, in addition to an attribute which defines the number of drawers of the desk, a desk inherits from the table class the color attribute and the attributes specifying various dimensions of the desk. Furthermore, a desk can perform the weight bearing member function described above and the behavior of the desk in performing the weight bearing member function is defined by the table class. The desk class can define additional member functions not defined by the table class, e.g., an open drawer member function, a place object in drawer member function, a remove object from drawer member function, and a close drawer member function. As described above, a subclass can also redefine an inherited member function, thereby superseding the inherited definition of the member function. For example, the table class can have a subclass which is a folding table class. The weight bearing member function described above can be redefined by the folding table class such that a folding table asked to bear a weight is verified to be in an unfolded, upright position prior to bearing any weight.
A member function defined by a class is performed by directing an object of the class to perform the member function. The particular member function performed is selected according to the class to which the object belongs. If the class to which the object belongs does not define such a member function, the member function is selected from the superclass which defines the member function and for which no subclass defines the member function. A first class is a superclass of a second class if the second class is a subclass of the first class. The member function is performed in the context of the state of the object directed to perform the member function. As described above, the particular behavior of a table which is directed to perform the weight bearing member function described above depends on the state of the table, including the particular dimensions of the table, the materials from which the table is made, and the amount of weight already supported by the table. For further description of object-oriented design and programming techniques, see B. Meyer, "Object-Oriented Software Construction", (Prentice-Hall, 1988).
In a distributed object-oriented computer system, clients are typically given object handles to reference remote objects. A remote object is an object whose class is implemented on a process that is different from the process where the object handle resides. Often, a remote object is implemented on a machine (hereinafter known as a remote machine) that is remote from the machine (hereinafter known as the local machine) where the object handle resides. The object handle identifies a remote object and enables invocation of the member functions of the remote object by the client. If a given client has an object handle referencing a particular remote object, then that client can pass a copy of that object handle to another client. The second client can then use the object handle to access the remote object and to invoke member functions of the remote object. Stub objects are typically employed in a local machine to reference a remote object whose class is implemented on a machine that is remote from the local machine.
For further description of object-oriented distributed systems, see (i) E. D. Lazowska et al "The Eden System: A Technical Review", IEEE Transactions on Software Engineering SE-11(1), January 1985; (ii) Jul et al "Fine Grained Mobility in the Emerald System", ACM Transactions on Computer Systems, 6(1), 1988; and (iii) B Liskov, "Distributed Programming in Argus", Communications of the ACM, 31(3), 1988.
Another helpful feature of object-oriented environments is referred to as interfaces. An interface is a collection of member function definitions without implementation. A programmer can employ interfaces to specify the member functions an object can perform. An interface defines the inputs, outputs, attributes, and exceptions of the member functions without the implementation. Implementations of a member function are the computer instructions that are executed by the computer to perform the member functions. While an interface specifies the inputs, outputs, attributes and exceptions of a member function, the interface does not include any computer instructions (i.e., the implementation of the member function). An object can have one or more interfaces. A class that specifies an interface typically includes implementation to perform all the member functions of the interface.
When the remote object includes multiple interfaces, a problem arises as to what extent the stub object on the local machine describes the interfaces of the remote object. Prior art systems address this problem using one of the following approaches.
In a first approach, the stub class in the local machine defines only the interface of the remote object that is explicitly requested prior to invoking a member function of that particular interface on the local machine. At any given time, the stub class (hereinafter referred to as the interface-specific stub class) only implements one of the interfaces of the remote object denoted by the stub. One disadvantage of this first approach is that any object instantiated from this stub class inaccurately responds to queries as to interface type on interface different to the one specifically requested.
A software language construct can be employed to query an object as to the object's interfaces (also referred to as interface type). For example, in JAVA the command instanceof (obj) yields a true or false to indicate whether the object includes the specified interface. Since, in this approach, the stub object does not accurately define all the interfaces of the remote object, these interface type queries cannot be used with confidence. For example, the stub object on the local machine can indicate that a particular interface is not included in a remote object where, in fact, the remote object includes that interface.
In a second approach, the stub class, associated with the remote object, defines and implements all the interfaces of the remote object. Although an object instantiated from this stub class will respond correctly to inquiries as to interface type, this approach requires the exporting of interfaces from the remote machine to the local machine, even for interfaces that are never used in the local machine. Moreover, this approach is inefficient and also opens security issues that need to be addressed.
For example, let us consider a remote object including three interfaces (interface A, interface B, and interface C). Interface A defines member functions X, Y and Z; interface C defines member functions Q, R and S, and interface B defines member function P. If any one of the member functions X, Y, Z, Q, R, S, or P are to be invoked on the local machine, a stub class is created that implements interfaces A, B and C regardless of whether member functions of those interfaces are ever invoked on the local machine.
An important and heretofore unsolved problem in distributed object oriented systems described using a language with a strong type system, is how to represent an object handle of a remote object so as to take advantage of the strong type system in the client machine and so as to ensure the object handle correctly identifies all interfaces of a remote object that are supported by the virtual machine on which the client application resides without having to export unnecessary implementation of interfaces not used by the local machine.